#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>
#include <sys/types.h>
#include <pthread.h>
#include <unistd.h>
#include "lib/hiredis.h"
#define Nthread      32
#define redisCmd     redisCommand 
#define freeRpl      freeReplyObject

//#define IP           "192.168.0.32"
#define IP          "192.168.1.150"
//#define IP          "10.15.1.53"
#define PORT         6379
#define TAIL         "_"
struct timeval       timeout = { 20, 0 };
pthread_mutex_t      mutex;
static size_t        count, count_prev = 0;

void* thread_timer(void *arg) {
   
    //int id = *(int *)arg;
    //(void)id;
    for (;;) {
        sleep(1);
        fprintf(stdout, "%ldw %ldw\r\n", (count-count_prev)/10000, count/10000);
        count_prev = count;
    }
    return NULL;
}

void* thread_start(void *arg) {

    int id = *(int *)arg;
    redisContext *redis;
    redisReply *reply;

    (void)id;
    redis = redisConnectWithTimeout((char*)IP, PORT, timeout);

    if (redis->err) {
        printf("Connection error: %s Port:%d\n", redis->errstr, PORT);
        exit(1);
    }
    /*while (1) {
        pthread_mutex_lock(&mutex);
        pthread_mutex_unlock(&mutex);
        __sync_add_and_fetch(&count, 1);
    }*/
    int i;
    while (1) {
        for (i = 0;i<=100 ; i++) {
            reply = redisCmd(redis,"SET key_%d val%s", i, TAIL);
            if(reply) freeReplyObject(reply);
            reply = redisCmd(redis,"GET key_%d", i);
            __sync_add_and_fetch(&count, 2);
            if(reply) freeReplyObject(reply);
            else {
                sleep(1);
                redis = redisConnectWithTimeout((char*)IP, PORT, timeout);
            }
        }
        redisFree(redis);
        redis = redisConnectWithTimeout((char*)IP, PORT, timeout); 
    }
    
    return 0;
}

int main(int argc, char** argv) {

    int             th_para[Nthread];
    int             i;
    int             ret;
    pthread_t       thread[Nthread], th_timer;
    pthread_attr_t  attr;

    pthread_attr_init(&attr);

    for (i = 0; i < Nthread; i++) {
    
        th_para[i] = i;
        if ((ret = pthread_create(&thread[i], &attr, thread_start, (void *)&th_para[i])) != 0) {
            exit(1);
        }
    }
    if ((ret = pthread_create(&th_timer, &attr, thread_timer, NULL)) != 0) {
        exit(1);
    }
    
    for (i = 0; i < Nthread; i++)
        pthread_join(thread[i],0);
    pthread_join(th_timer,0);
    fprintf(stdout, "%ld\r\n", count);    
    return 0;
}

